<?php
namespace app\index\controller;

use app\mall\model\MallOrder;
use app\mall\model\MallOrderCart;
use app\mall\model\MallOrderItem;
use app\mall\model\MallUserActionCollect;
use app\mall\model\MallUserAddress;
use app\mall\model\MallUsers;
use app\mall\service\ExpressService as ServiceExpressService;
use app\mall\service\GoodsService as ServiceGoodsService;
use app\mall\service\UserAction as ServiceUserAction;
use plugin\mall\service\UserOrder as ServiceUserOrder;
use plugin\payment\model\PluginPaymentAddress;
use plugin\payment\service\Balance;
use plugin\payment\service\contract\PaymentResponse;
use plugin\payment\service\Integral;
use plugin\payment\service\Payment;
use plugin\wemall\controller\api\Auth;
use plugin\wemall\model\PluginWemallOrder;
use plugin\wemall\model\PluginWemallOrderCart;
use plugin\wemall\model\PluginWemallOrderItem;
use plugin\wemall\model\PluginWemallUserCoupon;
use plugin\wemall\service\ExpressService;
use plugin\wemall\service\GoodsService;
use plugin\wemall\service\UserAction;
use plugin\wemall\service\UserCoupon;
use plugin\wemall\service\UserOrder;
use plugin\wemall\service\UserUpgrade;
use think\admin\extend\CodeExtend;
use think\admin\helper\QueryHelper;
use think\admin\Storage;
use think\db\Query;
use think\exception\HttpResponseException;

/**
 * 订单数据接口
 * @class Order
 * @package plugin\wemall\controller\api\auth
 */
class Order extends Base
{

    /**
     * 购买记录
     */
    public function list(){
        $this-> check_login();
        $this->user_info = MallUsers::mk()->where('id', $this->uid)->find();
        $this->list = MallOrderItem::where('unid',$this->uid)->order('id desc')->select();
        foreach ($this->list as $key =>&$value) {
            $value->is_collect = MallUserActionCollect::where('unid', $this->uid)->where('gcode', $value->gcode)->count();
        }
        return $this->fetch();
    }

    /**
     * 获取购买车数据
     * @return void
     */
    public function confirm_order(){
        $this-> check_login();
        $data = $this->_vali([
            'cart_ids.require'  => 'GOODS_EMPTY',
        ]);
        $cart_ids = explode('_', $data['cart_ids']);
        $list = MallOrderCart::mQuery()->with(['specs','goods'])->where('unid', $this->uid)->whereIn('id', $cart_ids)->order('id desc')->append(['spec'])->select();
        $this->user_info = MallUsers::mk()->where('id', $this->uid)->find();
        $this->list = $list; 
        // dump($this->list->toArray());die;
        return $this->fetch();
    }
    /**
     * 获取订单数据
     * @return void
     */
    public function get()
    {
        MallOrder::mQuery(null, function (QueryHelper $query) {
            if (empty(input('order_no'))) {
                $query->with('items')->where(['refund_status' => 0]);
            } else {
                $query->with(['items', 'address', 'sender']);
            }
            $query->in('status')->equal('order_no');
            $query->where(['unid' => $this->uid, 'deleted_status' => 0])->order('id desc');
            $this->success('获取订单成功！', $query->page(intval(input('page')), false, false, 10));
        });
    }

    /**
     * 创建订单数据
     * @return void
     */
    public function add()
    {
        try {
            // 请求参数检查
            $input = $this->_vali([
                'cart_ids.require' => 'Goods Require',
                'paymentType.require' => 'PaymentType Requiure',
                'deliveryType.require' => 'DeliveryType Require',
                'discountCode.value' => input('discountCode',''),
                'firstName.require' => 'firstName Require',
                'lastName.require' => 'lastName Require',
                'email.require' => 'Email Require',
                'phone.require' => 'phone Require',
                'rules.value'   => input('rules',''),
                'country.require' => 'country Require',
                'street.require' => 'street Require',
                'cardNumber.value' => input('cardNumber',''),
                'expirationDate.value' => input('expirationDate',''),
                'securityCode.value' => input('securityCode',''),
            ]);
            if ( empty($input['cart_ids'])) $this->error('参数无效！');
            if($input['paymentType'] == 2){
                //信用卡支付
                if($input['cardNumber'] == '' || $input['expirationDate'] == '' || $input['securityCode'] == ''){
                    $this->error('Please Fill In All The Required Credit Card Information!');
                }
            }
         
            // 生成统一编号
            do $extra = ['order_no' => $order['order_no'] = CodeExtend::uniqidNumber(16, 'N')];
            while (MallOrder::mk()->master()->where($extra)->findOrEmpty()->isExists());
         
        
            // 组装订单数据
            foreach (ServiceGoodsService::parse($this->uid, trim($input['rules'], ':;'), $input['cart_ids']) as $item) {
                if (empty($item['count'])) continue;
                if (empty($item['goods']) || empty($item['specs'])) $this->error('商品无效！');
                [$goods, $gspec, $count] = [$item['goods'], $item['specs'], intval($item['count'])];
               
                // 限制购买数量
                if (isset($goods['limit_maxnum']) && $goods['limit_maxnum'] > 0) {
                    $join = [MallOrderItem::mk()->getTable() => 'b'];
                    $where = [['a.unid', '=', $this->uid], ['a.status', '>', 1], ['b.gcode', '=', $goods['code']]];
                    $buyCount = MallOrder::mk()->alias('a')->join($join, 'a.order_no=b.order_no')->where($where)->sum('b.stock_sales');
                    if ($buyCount + $count > $goods['limit_maxnum']) $this->error('商品限购！');
                }
            
              
      
                // 订单详情处理
                $items[] = [
                    'unid'                  => $this->uid,
                    'order_no'              => $order['order_no'],
                    // 商品字段
                    'gsku'                  => $gspec['gsku'],
                    'gname'                 => $goods['name'],
                    'gcode'                 => $gspec['gcode'],
                    'ghash'                 => $gspec['ghash'],
                    'gspec'                 => $gspec['gspec'],
                    'gunit'                 => $gspec['gunit'],
                    'gcover'                => empty($gspec['gimage']) ? $goods['cover'] : $gspec['gimage'],
                    // 库存数量处理
                    'stock_sales'           => $count,
                    // 快递发货数据
                    'delivery_code'         => $goods['delivery_code'],
                    'delivery_count'        => $goods['rebate_type'] > 0 ? $gspec['number_express'] * $count : 0,
                    // 商品费用字段
                    'price_cost'            => $gspec['price_cost'],
                    'price_market'          => $gspec['price_market'],
                    'price_selling'         => $gspec['price_selling'],
                    // 商品费用统计
                    'total_price_cost'      => $gspec['price_cost'] * $count,
                    'total_price_market'    => $gspec['price_market'] * $count,
                    'total_price_selling'   => $gspec['price_selling'] * $count,
                    'total_allow_balance'   => $gspec['allow_balance'] * $count,
                    'total_allow_integral'  => $gspec['allow_integral'] * $count,
                    'total_reward_balance'  => $gspec['reward_balance'] * $count,
                    'total_reward_integral' => $gspec['reward_integral'] * $count,
        
           
                    'level_agent'           => $goods['level_agent'],
                    'level_upgrade'         => $goods['level_upgrade'],
                    // 是否参与返佣
                    'rebate_type'           => $goods['rebate_type'],
                    'rebate_amount'         => $goods['rebate_type'] > 0 ? $gspec['price_selling'] * $count : 0,
    
                ];
            }
            // 默认使用销售销售
            $order['rebate_amount'] = array_sum(array_column($items, 'rebate_amount'));
            $order['allow_balance'] = array_sum(array_column($items, 'total_allow_balance'));
            $order['allow_integral'] = array_sum(array_column($items, 'total_allow_integral'));
            $order['reward_balance'] = array_sum(array_column($items, 'total_reward_balance'));
            $order['reward_integral'] = array_sum(array_column($items, 'total_reward_integral'));
            // 会员及代理升级
            $order['level_agent'] = intval(max(array_column($items, 'level_agent')));
            $order['level_member'] = intval(max(array_column($items, 'level_upgrade')));
            // 订单发货类型
            $order['paymentType'] = $input['paymentType'];
            $order['deliveryType'] = $input['deliveryType'];
            $order['discountCode'] = $input['discountCode'];
            $order['firstName']    = $input['firstName'];
            $order['lastName']    = $input['lastName'];
            $order['email']    = $input['email'];
            $order['phone']    = $input['phone'];
            $order['country']    = $input['country'];
            $order['street']    = $input['street'];
            $order['cardNumber']    = $input['cardNumber'];
            $order['expirationDate']    = $input['expirationDate'];
            $order['securityCode']    = $input['securityCode'];
            $order['unid']   = $this->uid;
    
            // 统计商品数量
            $order['number_goods'] = array_sum(array_column($items, 'stock_sales'));
            $order['number_express'] = array_sum(array_column($items, 'delivery_count'));
            // 统计商品金额
            $order['amount_cost'] = array_sum(array_column($items, 'total_price_cost'));
            $order['amount_goods'] = array_sum(array_column($items, 'total_price_selling'));
            // 折扣后的金额
            $order['amount_discount'] = array_sum(array_column($items, 'discount_amount'));
            // 订单随减金额
            $order['amount_reduct'] = 0;
            if ($order['amount_reduct'] > $order['amount_goods']) {
                $order['amount_reduct'] = $order['amount_goods'];
            }
            // 统计订单金额
            $order['amount_real'] = round($order['amount_discount'] - $order['amount_reduct'], 2);
            $order['amount_total'] = $order['amount_goods'];
            $order['amount_profit'] = round($order['amount_real'] - $order['amount_cost']);
            // 写入商品数据
            $model = MallOrder::mk();
            
            $this->app->db->transaction(function () use ($order, $items, &$model) {
                $model->save($order) && MallOrderItem::mk()->saveAll($items);
            });
            // 同步库存销量
            foreach (array_unique(array_column($items, 'gcode')) as $gcode) {
                ServiceGoodsService::stock($gcode);
            }
            // 清理购物车数据
            if (count($carts = str2arr($input['cart_ids'])) > 0) {
                MallOrderCart::mk()->whereIn('id', $carts)->delete();
         
            }
            
      
            // 返回处理成功数据
            $this->success('下单成功！', array_merge($order, ['items' => $items]));
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            trace_file($exception);
            $this->error("下单失败，{$exception->getMessage()}");
        }
    }

 
    /**
     * 获取支付通道
     * @return void
     * @throws \think\admin\Exception
     */
    public function channel()
    {
        $this->success('获取支付通道！', [
           
        ]);
    }



    /**
     * 删除已取消订单
     * @return void
     */
    public function remove()
    {
        $order = $this->getOrderModel();
        if ($order->isEmpty()) $this->error('读取订单失败！');
        if ($order->getAttr('status') == 0) {
            if ($order->save([
                'status'         => 0,
                'deleted_time'   => date('Y-m-d H:i:s'),
                'deleted_status' => 1,
                'deleted_remark' => '用户主动删除订单！',
            ])) {
                // 触发订单删除事件
                $this->app->event->trigger('PluginWemallOrderRemove', $order);
                // 返回处理成功数据
                $this->success('删除成功！');
            } else {
                $this->error('删除失败！');
            }
        } else {
            $this->error('不可删除！');
        }
    }

    /**
     * 订单确认收货
     * @return void
     */
    public function confirm()
    {
        $order = $this->getOrderModel();
        if (in_array($order->getAttr('status'), [5, 6])) {
            // 触发订单确认事件
            $order->save([
                'status'         => 6,
                'confirm_time'   => date('Y-m-d H:i:s'),
                'confirm_remark' => '用户主动确认签收订单！',
            ]);
            $this->app->event->trigger('PluginWemallOrderConfirm', $order);
            // 返回处理成功数据
            $this->success('确认成功！');
        } else {
            $this->error('确认失败！');
        }
    }

    /**
     * 提交订单评论
     * @return void
     */
    public function comment()
    {
        $order = $this->getOrderModel();
        if (in_array($order->getAttr('status'), [6, 7])) try {
            // 接收评论数据
            $items = json_decode($this->request->post('data'), true);
            $this->app->db->transaction(function () use ($order, $items) {
                $order->save(['status' => 7]);
                $order->items()->select()->map(function (MallOrderItem $item) use ($items) {
                    if (!empty($input = $items[$item->getAttr('ghash')])) {
                        ServiceUserAction::comment($item, $input['rate'], $input['content'], $input['images']);
                    }
                });
            });
            $this->success('评论成功！');
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error($exception->getMessage());
        } else {
            $this->error('无需评论！');
        }
    }

    /**
     * 订单状态统计
     * @return void
     */
    public function total()
    {
        $data = ['t0' => 0, 't1' => 0, 't2' => 0, 't3' => 0, 't4' => 0, 't5' => 0, 't6' => 0, 't7' => 0];
        $query = MallOrder::mk()->where(['unid' => $this->uid, 'refund_status' => 0, 'deleted_status' => 0]);
        foreach ($query->field('status,count(1) count')->group('status')->cursor() as $item) {
            $data["t{$item['status']}"] = $item['count'];
        }
        $this->success('获取统计！', $data);
    }

    /**
     * 物流追踪查询
     * @return void
     */
    public function track()
    {
        try {
            $data = $this->_vali([
                'order_no.require' => 'order_no Is Require'
            ]);
            if(!$order = MallOrder::where('order_no',$data['order_no'])->find()){}
            throw new \Exception('Order Not Found');

        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error($exception->getMessage());
        }
    }

    /**
     * 获取输入订单模型
     * @return PluginWemallOrder
     */
    private function getOrderModel(): MallOrder
    {
        $map = $this->_vali(['unid.value' => $this->uid, 'order_no.require' => '单号不能为空']);
        $order = MallOrder::mk()->where($map)->findOrEmpty();
        if ($order->isEmpty()) $this->error('读取订单失败！');
        return $order;
    }
}